/**
 *
 * Copyright (c) 2009-2012 Envision Mobile Ltd. All rights reserved.
 *
 * Other software and company names mentioned herein or used for developing
 * and/or running the Envision Mobile Ltd's software may be trademarks or trade
 * names of their respective owners.
 *
 * Everything in the source code herein is owned by Envision Mobile Ltd.
 * The recipient of this source code hereby acknowledges and agrees that such
 * information is proprietary to Envision Mobile Ltd. and shall not be used, 
 * disclosed, duplicated, and/or reversed engineered except in accordance
 * with the express written authorization of Envision Mobile Ltd.
 *
 * Module: DrugExtraDTO.java
 * Project: ReyOfLight
 *
 * Description:
 *
 *
 * Developer:   10107896
 * Date:        2012-08-16
 * Version:		1.0
 *
 *
 */
package DTO;

import java.io.ByteArrayInputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Locale;

import org.Consts;
import org.Globals;
import org.Utility;

import GameTools.ydMath;
import GameTools.ydPoint;
import android.content.ContentValues;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.PorterDuff;
import android.graphics.RectF;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.util.Log;

/**
 * @author 10107896
 * 
 */
public class DrawingPlaneDTO extends BaseDTO implements Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = -8326353474170336768L;
	public int id;
	public int object_id;
	public Bitmap image;
	public ydPoint canvas_size;
	
	public ydPoint boundTL, boundBR;
	ydPoint scale;

	public ArrayList<DrawingActionDTO> drawingActions;
	
	public Matrix matrix;

	public DrawingPlaneDTO(ydPoint size) {
		id = -1;
		object_id = -1;
		image = Bitmap.createBitmap((int) size.x, (int) size.y,
				Bitmap.Config.ARGB_8888);
		canvas_size=new ydPoint(size);
		matrix=new Matrix();
		drawingActions = new ArrayList<DrawingActionDTO>();
	}
	
	

	public void addAction(DrawingActionDTO drawingAction) {
		drawingActions.add(drawingAction);
	}

	public void draw(Canvas canvas) {
		matrix.reset();
		if (drawingActions != null) {
			for (DrawingActionDTO drawingAction: drawingActions) {
				if(drawingAction.action.equals(Consts.DRAWING_ACTIONS_MOVE)){
					matrix.postTranslate(drawingAction.translate.x, drawingAction.translate.y);
				}
				else if(drawingAction.action.equals(Consts.DRAWING_ACTIONS_ROTATE)){
					ydPoint midPoint=ydMath.midPoint(boundTL, boundBR);
					float x=ydMath.vectorToRads(new ydPoint(drawingAction.position.x-midPoint.x, drawingAction.position.y-midPoint.y));
					matrix.postRotate(drawingAction.rads, drawingAction.pivot.x,drawingAction.pivot.y);
					
					
					Log.d("Rotate angle", drawingAction.pivot.toString() + " = " + drawingAction.rads +"");
				}
				else if(drawingAction.action.equals(Consts.DRAWING_ACTIONS_SCALE)){
	
					matrix.postScale(drawingAction.scale.x, drawingAction.scale.y, boundTL.x, boundTL.y);
					//boundBR.setCoordinates(drawingAction.position);
				}
			}
		}
		//applyTransform();
		canvas.setBitmap(image);
		canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
		if (drawingActions != null) {
			for (int i = 0; i < drawingActions.size(); i++) {
				((DrawingActionDTO) drawingActions.get(i)).draw(canvas);
			}
		}
	}

	public DrawingPlaneDTO(int id, SQLiteDatabase db) {
		this.id = id;

		Cursor c = null;
		if ("".equalsIgnoreCase(init_statement)) {

			String sql = "SELECT * FROM "+ Consts.TABLE_DRAWING_PLANE 	+ " WHERE " 	+ Consts.COLUMN_ID + " = " +id+"";
	    	c = db.rawQuery(sql, null);
			
			/*c = db.query(Consts.TABLE_DRAWING_PLANE, new String[] { Consts.COLUMN_IMAGE }, "_id=?",
					new String[] { id + "" }, null, null, null);*/

		}

		if (c != null) {
			if (c.moveToFirst()) {

				object_id=c.getInt(1);
				
				byte[] pic = (c.getBlob(2));
				ByteArrayInputStream imageStream = new ByteArrayInputStream(pic);
				image = BitmapFactory.decodeStream(imageStream);
				// img=((BitmapDrawable)Utility.byteArrayToDrawable(c.getBlob(0))).getBitmap();

				String size= c.getString(3);
				canvas_size=ydPoint.stringPairToydPoint(size);
				
			} else {
				Log.d("",
						"== something happened, could not extract from database");
			}
			if (c != null) {
				c.close();
			}
		} else {
			Log.d("", "== c was null");
		}
		matrix=new Matrix();
		image = Bitmap.createBitmap((int) canvas_size.x, (int) canvas_size.y,
				Bitmap.Config.ARGB_8888);
	}

	public static ArrayList<DrawingPlaneDTO> getDrawingPlanesInDatabase(SQLiteDatabase db, ObjectDTO obj) {

		ArrayList<DrawingPlaneDTO> drawingPlanes = new ArrayList<DrawingPlaneDTO>();

		try {
			// SELECT id FROM drug_extra WHERE drug_id=?
			// sqlite3_bind_int(statement, 1, drugUUID)
			String sql = "SELECT _id FROM " + Consts.TABLE_DRAWING_PLANE+ " WHERE " + Consts.COLUMN_OBJECT_ID + " = " + obj.intUuid;
			Cursor c = db.rawQuery(sql, null);

			while (c.moveToNext()) {

				int primaryKey = c.getInt(0);
				DrawingPlaneDTO drawingPlane = new DrawingPlaneDTO(primaryKey, db);
				drawingPlane.drawingActions=DrawingActionDTO.getDrawingActionsInDatabase(db, drawingPlane);
				drawingPlanes.add(drawingPlane);
			}

			if (c != null) {
				c.close();
			}

		} catch (Exception e) {
			e.printStackTrace();
			Log.d("", "== something went wrong, drugExtra, getDrugExtraDB");
		}

		return drawingPlanes;
	}
	
	public static ArrayList<DrawingPlaneDTO> getDrawingPlanesInDatabase(
			SQLiteDatabase db) {

		ArrayList<DrawingPlaneDTO> drawingPlanes = new ArrayList<DrawingPlaneDTO>();

		try {
			// SELECT id FROM drug_extra WHERE drug_id=?
			// sqlite3_bind_int(statement, 1, drugUUID)
			String sql = "SELECT _id FROM " + Consts.TABLE_OBJECT;
			Cursor c = db.rawQuery(sql, null);

			while (c.moveToNext()) {

				int primaryKey = c.getInt(0);
				DrawingPlaneDTO drawingPlane = new DrawingPlaneDTO(primaryKey, db);
				drawingPlane.drawingActions=DrawingActionDTO.getDrawingActionsInDatabase(db, drawingPlane);
				drawingPlanes.add(drawingPlane);
			}

			if (c != null) {
				c.close();
			}

		} catch (Exception e) {
			e.printStackTrace();
			Log.d("", "== something went wrong, drugExtra, getDrugExtraDB");
		}

		return drawingPlanes;
	}

	public void setAction(DrawingActionDTO drawingAction) {
		if (drawingActions.size() > 0) {
			drawingActions.set(drawingActions.size() - 1, drawingAction);
		}
	}

	public void setAction(int i, DrawingActionDTO drawingAction) {
		drawingActions.set(i, drawingAction);

	}

	public void save(int object_id) {
		this.object_id=object_id;
		insertIntoDatabase(Globals.sqlDB);
		
		for(DrawingActionDTO d: drawingActions){
			
			d.save(id);
			
			/*d.drawing_plane_id=id;
			d.insertInDatabase(Globals.sqlDB);*/
		}
		
	}
	
	public boolean insertIntoDatabase(SQLiteDatabase db) {
		this.db=db;
		try {
			ContentValues values = new ContentValues();
			values.put(Consts.COLUMN_OBJECT_ID, object_id);
			
			byte[] img=Utility.bitmaptoByteArray(image);
			values.put(Consts.COLUMN_IMAGE, img);
			
			values.put(Consts.COLUMN_CANVAS_SIZE, canvas_size.toString());

			int r_id = (int) db.insert(Consts.TABLE_DRAWING_PLANE, null, values);

			if (r_id>0){
				id=r_id;
				Log.d("", "== was successfully inserted in db, DRAWING_PLANE");
			}
			else{
				Log.d("", "== unsuccessful in inserting in db, DRAWING_PLANE");
			}
			return r_id>0;
		} catch (Exception e) {
			e.printStackTrace();

			Log.d("", "== unsucessful in inserting in db, DRAWING_PLANE, exception");
		}
		return false;
	}

	public static void deleteDrawingPlanesForObjectInDatabase(int objID,
			SQLiteDatabase db) {
		ArrayList<Integer> drawingPlanesID =DrawingPlaneDTO.getDrawingPlanesIDForObjectInDatabase(objID, db);
		
		for (Integer pk : drawingPlanesID){
			DrawingActionDTO.deleteDrawingAction(pk, db);
			DrawingPlaneDTO.deleteDrawingPlane(pk, db);
		}
		
	}

	private static void deleteDrawingPlane(Integer pk, SQLiteDatabase db) {
		try {
			boolean state = db.delete(Consts.TABLE_DRAWING_PLANE, "_id=?",
					new String[] { pk + "" }) > 0;

			if (state)
				Log.d("", "== successfully deleted, dose");
			else
				Log.d("", "== problem deleting, dose");
		} catch (SQLException e) {
			Log.e("Database Error: ", e.toString());
			e.printStackTrace();
		}
		
	}

	public static ArrayList<Integer> getDrawingPlanesIDForObjectInDatabase(
			int objID, SQLiteDatabase db) {
		ArrayList<Integer> drawingPlanesID = new ArrayList<Integer>();

		try {
			// SELECT id FROM drug_extra WHERE drug_id=?
			// sqlite3_bind_int(statement, 1, drugUUID)
			String sql = "SELECT _id FROM " + Consts.TABLE_DRAWING_PLANE + " WHERE " + Consts.COLUMN_OBJECT_ID + "=" + objID +"";
			Cursor c = db.rawQuery(sql, null);

			while (c.moveToNext()) {

				int primaryKey = c.getInt(0);
				//DrawingPlaneDTO obj = new DrawingPlaneDTO(primaryKey, db);
				drawingPlanesID.add(primaryKey);
			}

			if (c != null) {
				c.close();
			}

		} catch (Exception e) {
			e.printStackTrace();
			Log.d("", "== something went wrong, drugExtra, getDrugExtraDB");
		}

		return drawingPlanesID;
	}



	public void calculateBounds() {
		boundTL=new ydPoint(1000, 1000);
		boundBR=new ydPoint(0, 0);
		
		ArrayList<ydPoint> pathPoints=new ArrayList<ydPoint>();
		
		for(DrawingActionDTO da: drawingActions){
			if(da.action.equals(Consts.DRAWING_ACTIONS_BRUSH) || da.action.equals(Consts.DRAWING_ACTIONS_Shape) 
					|| da.action.equals(Consts.DRAWING_ACTIONS_TEXT)){
				
				RectF rect=new RectF();
				
				da.path.computeBounds(rect, true);
				
				boundTL.setCoordinates(rect.left, rect.top);
				boundBR.setCoordinates(rect.right, rect.bottom);
				
/*				pathPoints=Utility.pathToArrayList(da.path);
				
				
				
				for( ydPoint point: pathPoints){
					if(point.x>boundBR.x){
						boundBR.x=point.x;
					}
					if(point.x<boundTL.x){
						boundTL.x=point.x;
					}
					
					if(point.y>boundBR.y){
						boundBR.y=point.y;
					}
					if(point.y<boundTL.y){
						boundTL.y=point.y;
					}
				}*/
			}
		}
		
	}
	

}
